#pragma once

#include "Misc/CommonMacros.h"
#include "Containers/String.h"
#include "Containers/Delegate.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/RectangleWidget.h"
#include "Texture/Texture2D.h"
#include "Font/StaticTextArranger.h"
#include "ButtonWidget.m.h"


class RMouseWidget;
class RMaterial;

RSTRUCT(ExtraHeader=["Material/Material.h"] )
struct WHENGINE_API SButtonIcon
{
    ROBJECT

    RFIELD()
    TWidgetAttribute<int64_t> Width=12;

    RFIELD()
    TWidgetAttribute<int64_t> Height=12;

    //material or texture
    //use material if material is not null
    //use texture if material is null
    //RFIELD()
    //TSharedObjectPtr<RMaterial> Material;

    RFIELD()
    TWidgetAttribute<RTexture2DPtr> Texture;


};

RSTRUCT()
struct WHENGINE_API SButtonBackgroundStyle
{
    ROBJECT

    RFIELD()
    TWidgetAttribute<bool> Fill=true;

    RFIELD()
    TWidgetAttribute<SColor> FillColor=SColor(1,1,1,1);
    
    RFIELD()
    TWidgetAttribute<float> BorderSize=0;
    
    RFIELD()
    TWidgetAttribute<SColor> BorderColor=SColor(1,1,1,1);

    RFIELD()
    TWidgetAttribute<float> CornerRadius=0;
};

RSTRUCT()
struct WHENGINE_API STextStyle
{
    ROBJECT

    RFIELD()
    TWidgetAttribute<SColor> Color=SColor(1,1,1,1);

    RFIELD()
    TWidgetAttribute<TSharedObjectPtr<RFont>> Font;

    RFIELD()
    TWidgetAttribute<int64_t> FontSize=16;
};

RCLASS()
class WHENGINE_API RButtonWidget: public RWidget
{
    ROBJECT
public:    
    RButtonWidget();

    //set background widget or background style    
    //if set background widget, will use the widget as background widget
    //RFUNCTION()
    //void SetBackgroundWidget(TSharedObjectPtr<RWidget> InBackgroundWidget);

    //set background widget or background style
    //if set background style, will create a rectangle widget as background widget
    RFIELD()
    SButtonBackgroundStyle BackgroundStyle;

    //set background color in BackgroundStyle
    //equivalent to set BackgroundStyle.FillColor with a lambda function
    //this function is for quick set hover color
    void SetHovorColor(SColor InColor,SColor InHorveredColor);

    //set Icon widget or Icon style
    //if set Icon widget, will use the widget as Icon widget
    //RFUNCTION()
    //void SetIconWidget(TSharedObjectPtr<RWidget> InIconWidget);

    //set Icon widget or Icon style
    //if set Icon style, will create a image widget as Icon widget
    RFIELD()
    SButtonIcon Icon;
    
    //set text widget or text 
    //if set text widget, will use the widget as text widget
    //RFUNCTION()
    //void SetTextWidget(TSharedObjectPtr<RWidget> InTextWidget);

    //set text widget or text 
    //if set text , will create a text widget as text widget
    RFIELD()
    TWidgetAttribute<CString> Text;

    //set text widget or text style
    //if set text style, will create a text widget as text widget
    RFIELD()
    STextStyle TextStyle;

    //distance between icon and text
    //only work when icon and text both exist
    RFIELD()
    float IconTextDistance=0;

    //events

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnClicked;

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnDoubleClicked;

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnPressed;

    RFIELD()
    TScriptDelegate<bool(const SMouseButtonEvent&)> OnReleased;

    RFUNCTION()
    bool IsPressed();

    RFUNCTION()
    bool IsHovered();

    SVec2 GetTextSize();
protected:

    TWeakObjectPtr<RMouseWidget> MouseWidget;
    
    bool NotifyOnClicked(const SMouseButtonEvent& MouseEvent);
    bool NotifyOnDoubleClicked(const SMouseButtonEvent& MouseEvent);
    bool NotifyOnPressed(const SMouseButtonEvent& MouseEvent);
    bool NotifyOnReleased(const SMouseButtonEvent& MouseEvent);
    void OnHovered();
    void OnUnhovered();

    bool bIsPressed=false;
    bool bIsHovered=false;

    void PaintSelf(uint16_t& InZOrder,const SRect& InClipArea) override;

    CStaticTextArranger TextArranger;
};